package com.zx.mes.hyl.config;

import com.zx.mes.hyl.aspect.LogMathAspect;
import com.zx.mes.hyl.math.MathCalculator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * aop config
 *
 * aop source code analysis
 * 1.引入组件 AspectJAutoProxyRegistrar.class
 * AspectJAutoProxyRegistrar 实现 ImportBeanDefinitionRegistrar
 *      1.注册bean AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
 *      2.return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
 * 2.AnnotationAwareAspectJAutoProxyCreator.class (inherit structure)这个是真正要注入创建的对象
 *      AnnotationAwareAspectJAutoProxyCreator
 *          AspectJAwareAdvisorAutoProxyCreator
 *              AbstractAdvisorAutoProxyCreator
 *                  AbstractAutoProxyCreator
 *                      ProxyProcessorSupport
 *                          ProxyConfig
 *                          Ordered(interface)
 *                          BeanClassLoaderAware(interface)
 *                          AopInfrastructureBean(interface)
 *                      SmartInstantiationAwareBeanPostProcessor(interface)
 *                          InstantiationAwareBeanPostProcessor(interface)
 *                              BeanPostProcessor(interface)
 *                      BeanFactoryAware(interface)
 * 3.主要的方法调用栈
 *      registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
 *          /// 1.注册AnnotationAwareAspectJAutoProxyCreator.class
 *          /// 2.判断容器org.springframework.aop.config.internalAutoProxyCreator是否存在
 *          /// 3.不存在则直接注册创建一个
 *          registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
 *
 * 4.根据BeanPostProcessor与BeanFactoryAware的一些特点分析
 *      AbstractAutoProxyCreator.setBeanFactory
 *      AbstractAutoProxyCreator.postProcessBeforeInitialization
 *      AbstractAutoProxyCreator.postProcessAfterInitialization
 *
 *      AbstractAdvisorAutoProxyCreator.setBeanFactory-->AbstractAutoProxyCreator.setBeanFactory-->initBeanFactory
 *
 *      AspectJAwareAdvisorAutoProxyCreator
 *
 *      AnnotationAwareAspectJAutoProxyCreator.initBeanFactory-->AbstractAdvisorAutoProxyCreator.initBeanFactory
 *
 * 5.aop test debug
 *      1.IOC注册(1.无参,2.配置文件,3.刷新容器)
 *      2.registerBeanPostProcessors(beanFactory) 注册后置bean处理器
 *          /// 1.String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
 *          ///  获取所的BeanPostProcessor名称
 *          /// 2.Separate between BeanPostProcessors that implement PriorityOrdered,
 *                Ordered, and the rest.
 *                List类型:priorityOrderedPostProcessors,internalPostProcessors,orderedPostProcessorNames,nonOrderedPostProcessorNames
 *          /// 3.BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);遍历第一步骤中的postProcessorNames
 *                  getBean-->doGetBean-->getSingleton-->createBean(如果有缓存单例,那么直接获取,如果没有则创建)
 *                      createBean
 *                          /// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance
 *                          /// 先使用后置处理器返回一个代理bean对象
 *                          Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
 *                          /// 如果上述操作不生效,即直接执行下述操作创建
 *                          Object beanInstance = doCreateBean(beanName, mbdToUse, args);
 *                              doCreateBean
 *                                  instanceWrapper = createBeanInstance(beanName, mbd, args);
 *                                  /// 下面两个操作进行初使化
 *                                  /// Populate the bean instance in the given BeanWrapper with the property values
 *                                  /// 使用属性值集合给被包装对象赋值
 *                                  populateBean(beanName, mbd, instanceWrapper);
 *                                  exposedObject = initializeBean(beanName, exposedObject, mbd);(此方法执行了这些方法)
 *                                      /// xxxAware
 *                                      invokeAwareMethods(beanName, bean);
 *                                      /// BeanPostProcessor
 *                                      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 *                                      /// 对象实例化后,调用一些初使化方法
 *                                      invokeInitMethods(beanName, wrappedBean, mbd);
 *                                      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 *          PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)
 *
 *
 *
 * @author 华云龙
 * @date 2018-10-26
 */
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {

    @Bean
    public MathCalculator mathCalculator() {
        return new MathCalculator();
    }

    @Bean
    public LogMathAspect logMathAspect(){
        return new LogMathAspect();
    }
}
